package com.cdhk.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.cdhk.constant.PlmConstant;
import com.cdhk.dto.ExportFileDTO;
import com.cdhk.dto.ExportPartReportDTO;
import com.cdhk.dto.IbaValueDTO;
import com.cdhk.dto.ProductPartDetailDTO;
import com.cdhk.dto.ProductProcessMaterialDTO;
import com.cdhk.mapper.CommonMapper;
import com.cdhk.service.CommonService;
import com.cdhk.service.ExportPartReportService;
import com.hustcad.plm.pdm.form.model.vo.PdmFormColumn;
import com.hustcad.plm.pdm.form.service.TyplmDynamicFormService;
import com.hustcad.plm.pdm.partbom.dto.ChildPartsFiltersDTO;
import com.hustcad.plm.pdm.partbom.dto.ExpandBomTreeByFilterDTO;
import com.hustcad.plm.pdm.partbom.dto.PartBomTree;
import com.hustcad.plm.pdm.partbom.service.TyplmPartBomService;
import com.hustcad.plm.pdm.partbom.service.TyplmPartService;
import com.hustcad.plm.pdm.partbom.vo.PdmPartFormData;
import com.hustcad.plm.pdm.partbom.vo.TyPartAllVO;
import com.hustcad.plm.pdm.type.model.vo.TypeTree;
import com.hustcad.plm.pdm.type.service.TyplmTypeService;
import com.ty.basic.constant.TableTypeConstrant;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigInteger;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class ExportPartReportServiceImpl implements ExportPartReportService {

    @Resource
    private TyplmPartBomService typlmPartBomService;
    @Resource
    private TyplmPartService typlmPartService;
    @Resource
    private TyplmDynamicFormService typlmDynamicFormService;
    @Resource
    private TyplmTypeService typlmTypeService;
    @Value("${rt.tool.export.model.path:templates/产品零部件明细表模板.xlsx}")
    private String templateForProductPartsListPath;
    @Value("${rt.tool.export.model.path:templates/产品外购件明细表.xlsx}")
    private String listOfPurchasedPartsForProductsPath;
    @Value("${rt.tool.export.model.path:templates/产品工艺材料明细表.xlsx}")
    private String productProcessMaterialList;
    @Value("${rt.tool.export.model.path:templates/产品电气件明细表.xlsx}")
    private String productElectricalPartsList;
    @Resource
    private CommonService commonService;
    @Resource
    private CommonMapper commonMapper;

    @Override
    public void exportPartDetailReport(String partOid, HttpServletResponse response) {
        List<PartBomTree> partBomTreeList = queryPartBomTreeList(partOid);
        if (CollUtil.isNotEmpty(partBomTreeList)){
            Map<String, String> ibaIdAndNameByType = getIbaIdAndNameByType(TableTypeConstrant.TY_PART_OTYPE);
            String weightId = ibaIdAndNameByType.get(PlmConstant.IBA_WEIGHT);
            String materialId = ibaIdAndNameByType.get(PlmConstant.IBA_MATERIAL);
            PartBomTree partBomTree = partBomTreeList.get(0);
            LinkedHashMap<String, ProductPartDetailDTO> result = new LinkedHashMap<>();
            partBomTree.setAmount(1.0);
            buildData(partBomTree,result,weightId,materialId,1.0);
            if(CollUtil.isNotEmpty( result)){
                // TODO 导出到Excel
                String name = partBomTree.getName();
                List<String> modelValues = partBomTree.getPartIbaAttributeMap().get(ibaIdAndNameByType.get(PlmConstant.IBA_MODEL));
                String model = "";
                if(CollUtil.isNotEmpty( modelValues)){
                    model = modelValues.get(0);
                }
                String templateFileName = commonService.getFilePath(templateForProductPartsListPath);
                ExportFileDTO destFile = commonService.getDestFile(partBomTree.getObjectNumber() + "产品零部件明细表");
                exportPartDetailToExcel(result.values(),templateFileName,destFile,name,model,response);
            }
        }
    }

    private void exportPartDetailToExcel(Collection<ProductPartDetailDTO> values, String templateFileName,
                                         ExportFileDTO fileDTO, String name, String model, HttpServletResponse response) {
        File sourceFile = new File(templateFileName);
        File destFile = new File(fileDTO.getFilePath());
        try {
            // 确保目标文件的目录存在
            copyModelFileToDestFile(destFile, sourceFile);

            FileInputStream fis = new FileInputStream(destFile);
            Workbook workbook = new XSSFWorkbook(fis);
            Sheet sheet = workbook.getSheetAt(0);

            CellStyle style = getCellStyle(workbook);

            createAndSetCell(sheet.getRow(2), 1, name, style);
            createAndSetCell(sheet.getRow(3), 1, model, style);

            int rowNum = 5;
            int i = 1;
            for (ProductPartDetailDTO dto : values) {
                Row row = sheet.createRow(rowNum++);
                createAndSetCell(row, 0, String.valueOf(i++), style); // 序号
                createAndSetCell(row, 1, StringUtils.defaultIfBlank(dto.getPartName(), ""), style);
                createAndSetCell(row, 2, StringUtils.defaultIfBlank(dto.getDrawingNumber(), ""), style);
                createAndSetCell(row, 3, StringUtils.defaultIfBlank(dto.getMaterial(), ""), style);
                createAndSetCell(row, 4, StringUtils.defaultIfBlank(dto.getQuantityPerUnit(), ""), style);
                createAndSetCell(row, 5, StringUtils.defaultIfBlank(dto.getUnit(), ""), style);
                createAndSetCell(row, 6, StringUtils.defaultIfBlank(dto.getWeightKg(), ""), style);
                createAndSetCell(row, 7, "", style);
            }
            responseFile(fileDTO, response, workbook);
        }catch (Exception e){
            e.printStackTrace();
            throw new RuntimeException(e);
        }finally {
            destFile.delete();
        }
    }

    private static CellStyle getCellStyle(Workbook workbook) {
        CellStyle style = workbook.createCellStyle();
        style.setAlignment(HorizontalAlignment.CENTER); // 水平居中
        style.setVerticalAlignment(VerticalAlignment.CENTER); // 垂直居中
        style.setBorderTop(BorderStyle.THIN); // 上边框
        style.setBorderBottom(BorderStyle.THIN); // 下边框
        style.setBorderLeft(BorderStyle.THIN); // 左边框
        style.setBorderRight(BorderStyle.THIN); // 右边框
        return style;
    }

    private static void createAndSetCell(Row row, int columnIndex, String value, CellStyle style) {
        if ("null".equals(value)) {
            value = "";
        }
        Cell cell = row.createCell(columnIndex);
        cell.setCellValue(value);
        cell.setCellStyle(style);
    }

    private void buildData(PartBomTree partBomTree, LinkedHashMap<String, ProductPartDetailDTO> result, String weightId, String materialId, Double parentPartAmount) {
        String partNumber = partBomTree.getObjectNumber();
        if(result.containsKey(partNumber)){
            ProductPartDetailDTO partReportDTO = result.get(partNumber);
            Double amount = partBomTree.getAmount() * parentPartAmount;
            String quantityPerUnit = partReportDTO.getQuantityPerUnit();
            if(StringUtils.isNotBlank(quantityPerUnit)){
                amount = amount + Double.parseDouble(quantityPerUnit);
            }
            partReportDTO.setQuantityPerUnit(String.valueOf(amount));
        }else {
            ProductPartDetailDTO partReportDTO = new ProductPartDetailDTO();
            partReportDTO.setPartName(partBomTree.getName());
            partReportDTO.setDrawingNumber(partNumber);
            Map<String, List<String>> partIbaAttributeMap = partBomTree.getPartIbaAttributeMap();

            List<String> weight = partIbaAttributeMap.get(weightId);
            if (CollUtil.isNotEmpty(weight)) {
                partReportDTO.setWeightKg(weight.get(0));
            } else {
                partReportDTO.setWeightKg("");
            }

            List<String> material = partIbaAttributeMap.get(materialId);
            if (CollUtil.isNotEmpty(material)) {
                partReportDTO.setMaterial(material.get(0));
            } else {
                partReportDTO.setMaterial("");
            }

            Double amount = partBomTree.getAmount() * parentPartAmount;
            partReportDTO.setQuantityPerUnit(String.valueOf(amount));
            partReportDTO.setUnit(partBomTree.getUnitName());
            result.put(partNumber,partReportDTO);
            HashSet<PartBomTree> children = partBomTree.getChildren();
            if (CollUtil.isNotEmpty(children)) {
                for (PartBomTree child : children) {
                    buildData(child,result,weightId,materialId,amount);
                }
            }
        }
    }


    private List<PartBomTree> queryPartBomTreeList(String partOid) {
        TyPartAllVO tyPartAllVO = typlmPartService.queryPartAllVO(new BigInteger(partOid), TableTypeConstrant.TY_PART_OTYPE);

        List<ChildPartsFiltersDTO> conditions = new ArrayList<>();
        ChildPartsFiltersDTO childPartsFiltersDTO = new ChildPartsFiltersDTO();
        childPartsFiltersDTO.setExpandCondition("latest");
        childPartsFiltersDTO.setView(tyPartAllVO.getView());
        conditions.add(childPartsFiltersDTO);
        ExpandBomTreeByFilterDTO expandBomTreeByFilterDTO = new ExpandBomTreeByFilterDTO();
        expandBomTreeByFilterDTO.setConditions(conditions);
        expandBomTreeByFilterDTO.setFatherOid(partOid);//设置oid
        expandBomTreeByFilterDTO.setFatherNumber(tyPartAllVO.getPartnumber());
        expandBomTreeByFilterDTO.setFatherOtype(TableTypeConstrant.TY_PART_OTYPE);
        expandBomTreeByFilterDTO.setExpandLevel("N");
        expandBomTreeByFilterDTO.setIbaColumns(null);
        expandBomTreeByFilterDTO.setIsQueryIBA(true);
        expandBomTreeByFilterDTO.setIsNestedTree(true);
        return this.typlmPartBomService.expandBomTreeByFilterNew(
                expandBomTreeByFilterDTO, true).getPartBomTreeList();
    }

    public Map<String, String> getIbaIdAndNameByType(String typeName) {
        Map<String, String> map = new HashMap<>();
        Set<BigInteger> set = new HashSet<>();

        List<String> typeNameList = Collections.singletonList(typeName);
        List<TypeTree> treeList = this.typlmTypeService.queryTypeTreeByInthid(typeNameList);
        getTypeOidByTypeName(treeList, set);

        if (set.isEmpty()) {
            return map;
        }

        for (BigInteger oid : set) {
            String oidStr = oid.toString();
            PdmPartFormData pdmPartFormData = this.typlmDynamicFormService.newQueryPartFormWithoutDetail(oidStr, null, null);
            List<PdmFormColumn> formData = pdmPartFormData.getPdmForm().getFormData();

            for (PdmFormColumn param : formData) {
                if (param.getOid() == null) {
                    continue;
                }
                map.put(param.getProp(), param.getIbaOid());
            }
        }

        return map;
    }

    private void getTypeOidByTypeName(List<TypeTree> treeList, Set<BigInteger> set) {
        for (TypeTree typeTree : treeList) {
            List<TypeTree> childList = typeTree.getChildList();
            set.add(typeTree.getOid());
            getTypeOidByTypeName(childList, set);
        }
    }

    @Override
    public void exportOutSourcingDetailReport(String partOid, HttpServletResponse response) {
        List<PartBomTree> partBomTreeList = queryPartBomTreeList(partOid);
        if(CollUtil.isNotEmpty(partBomTreeList)){
            LinkedHashMap<String, ExportPartReportDTO> result = new LinkedHashMap<>();
            Map<String, String> ibaIdAndNameByType = getIbaIdAndNameByType(TableTypeConstrant.TY_PART_OTYPE);
            String codenameId= ibaIdAndNameByType.get(PlmConstant.IBA_CODENAME);
            String materialId = ibaIdAndNameByType.get(PlmConstant.IBA_MATERIAL);
            String ggxhId = ibaIdAndNameByType.get(ibaIdAndNameByType.get(PlmConstant.IBA_GGXH));
            PartBomTree partBomTree = partBomTreeList.get(0);
            partBomTree.setAmount(1.0);
            dealOutSourcingData(partBomTree, result, codenameId, materialId, ggxhId, 1.0);

            String ibaModelId = ibaIdAndNameByType.get(PlmConstant.IBA_MODEL);
            String templateFileName = commonService.getFilePath(listOfPurchasedPartsForProductsPath);
            ExportFileDTO destFile = commonService.getDestFile(partBomTree.getObjectNumber() + "产品外购件明细表");
            exportPartReportToExcel(result.values(), templateFileName, destFile, partBomTree, response, ibaModelId);
        }
    }

    private void exportPartReportToExcel(Collection<ExportPartReportDTO> values, String templateFileName,
                                         ExportFileDTO fileDTO, PartBomTree partBomTree,
                                         HttpServletResponse response,String ibaModelId) {
        if(CollUtil.isEmpty(values)){
            return;
        }
        String name = partBomTree.getName();
        List<String> modelValues = partBomTree.getPartIbaAttributeMap().get(ibaModelId);
        String model = "";
        if(CollUtil.isNotEmpty(modelValues)){
            model = modelValues.get(0);
        }
        File sourceFile = new File(templateFileName);
        File destFile = new File(fileDTO.getFilePath());
        try {
            // 确保目标文件的目录存在
            copyModelFileToDestFile(destFile, sourceFile);

            FileInputStream fis = new FileInputStream(destFile);
            Workbook workbook = new XSSFWorkbook(fis);
            Sheet sheet = workbook.getSheetAt(0);

            CellStyle style = getCellStyle(workbook);

            createAndSetCell(sheet.getRow(2), 1, name, style);
            createAndSetCell(sheet.getRow(3), 1, model, style);

            int rowNum = 5;
            int i = 1;
            for (ExportPartReportDTO dto : values) {
                Row row = sheet.createRow(rowNum++);
                createAndSetCell(row, 0, String.valueOf(i++), style); // 序号
                createAndSetCell(row, 1, StringUtils.defaultIfBlank(dto.getPartName(), ""), style);
                createAndSetCell(row, 2, StringUtils.defaultIfBlank(dto.getCodename(), ""), style);
                createAndSetCell(row, 3, StringUtils.defaultIfBlank(dto.getMaterial(), ""), style);
                createAndSetCell(row, 4, StringUtils.defaultIfBlank(dto.getSpecification(), ""), style);
                createAndSetCell(row, 5, StringUtils.defaultIfBlank(dto.getQuantityPerUnit(), ""), style);
                createAndSetCell(row, 6, StringUtils.defaultIfBlank(dto.getUnit(), ""), style);
                createAndSetCell(row, 7, "", style);
            }
            responseFile(fileDTO, response, workbook);
        }catch (Exception e){
            e.printStackTrace();
            throw new RuntimeException(e);
        }finally {
            destFile.delete();
        }

    }

    private void dealOutSourcingData(PartBomTree partBomTree, LinkedHashMap<String, ExportPartReportDTO> result,
                                     String codenameId, String materialId, String ggxhId, Double parentPartAmount) {
        String typeName = partBomTree.getTypeName();
        if(PlmConstant.TYPE_OUTSOURCING.equals(typeName)){
            String partNumber = partBomTree.getObjectNumber();
            if(result.containsKey(partNumber)){
                ExportPartReportDTO partReportDTO = result.get(partNumber);
                Double amount = partBomTree.getAmount() * parentPartAmount;
                String quantityPerUnit = partReportDTO.getQuantityPerUnit();
                if(StringUtils.isNotBlank(quantityPerUnit)){
                    amount = amount + Double.parseDouble(quantityPerUnit);
                }
                partReportDTO.setQuantityPerUnit(String.valueOf(amount));
            }else {
                ExportPartReportDTO partReportDTO = new ExportPartReportDTO();
                partReportDTO.setPartName(partBomTree.getName());
                Map<String, List<String>> partIbaAttributeMap = partBomTree.getPartIbaAttributeMap();
                List<String> codename = partIbaAttributeMap.get(codenameId);
                if (CollUtil.isNotEmpty(codename)) {
                    partReportDTO.setCodename(codename.get(0));
                } else {
                    partReportDTO.setCodename("");
                }

                List<String> material = partIbaAttributeMap.get(materialId);
                if (CollUtil.isNotEmpty(material)) {
                    partReportDTO.setMaterial(material.get(0));
                } else {
                    partReportDTO.setMaterial("");
                }

                List<String> ggxh = partIbaAttributeMap.get(ggxhId);
                if (CollUtil.isNotEmpty(ggxh)) {
                    partReportDTO.setSpecification(ggxh.get(0));
                } else {
                    partReportDTO.setSpecification("");
                }

                Double amount = partBomTree.getAmount() * parentPartAmount;
                partReportDTO.setQuantityPerUnit(String.valueOf(amount));
                partReportDTO.setUnit(partBomTree.getUnitName());
                result.put(partNumber,partReportDTO);
                HashSet<PartBomTree> children = partBomTree.getChildren();
                if (CollUtil.isNotEmpty(children)) {
                    for (PartBomTree child : children) {
                        dealOutSourcingData(child,result,codenameId,materialId,ggxhId,amount);
                    }
                }
            }
        }
    }

    @Override
    public void exportElectricalDetailReport(String partOid, HttpServletResponse response) {
        List<PartBomTree> partBomTreeList = queryPartBomTreeList(partOid);
        Map<String, String> ibaIdAndNameByType = getIbaIdAndNameByType(TableTypeConstrant.TY_PART_OTYPE);
        String codenameId= ibaIdAndNameByType.get(PlmConstant.IBA_CODENAME);
        String materialId = ibaIdAndNameByType.get(PlmConstant.IBA_MATERIAL);
        String ggxhId = ibaIdAndNameByType.get(ibaIdAndNameByType.get(PlmConstant.IBA_GGXH));
        String isElectricalId = ibaIdAndNameByType.get(PlmConstant.IBA_ELECTRICAL);
        LinkedHashMap<String, ExportPartReportDTO> result = new LinkedHashMap<>();
        PartBomTree partBomTree = partBomTreeList.get(0);
        partBomTree.setAmount(1.0);
        dealElectricalData(partBomTree, result, codenameId, materialId, ggxhId, isElectricalId, 1.0);
        String ibaModelId = ibaIdAndNameByType.get(PlmConstant.IBA_MODEL);
        String templateFileName = commonService.getFilePath(productElectricalPartsList);
        ExportFileDTO destFile = commonService.getDestFile(partBomTree.getObjectNumber() + "产品电气件明细表");
        exportPartReportToExcel(result.values(), templateFileName, destFile, partBomTree, response, ibaModelId);
    }

    private void dealElectricalData(PartBomTree partBomTree, LinkedHashMap<String, ExportPartReportDTO> result,
                                    String codenameId, String materialId, String ggxhId, String isElectricalId,double parentPartAmount) {
        Map<String, List<String>> partIbaAttributeMap = partBomTree.getPartIbaAttributeMap();
        List<String> isElectrical = partIbaAttributeMap.get(isElectricalId);
        if(CollUtil.isNotEmpty(isElectrical) && "是".equals(isElectrical.get(0))){
            String partNumber = partBomTree.getObjectNumber();
            if(result.containsKey(partNumber)){
                ExportPartReportDTO partReportDTO = result.get(partNumber);
                Double amount = partBomTree.getAmount() * parentPartAmount;
                String quantityPerUnit = partReportDTO.getQuantityPerUnit();
                if(StringUtils.isNotBlank(quantityPerUnit)){
                    amount = amount + Double.parseDouble(quantityPerUnit);
                }
                partReportDTO.setQuantityPerUnit(String.valueOf(amount));
            }else {
                ExportPartReportDTO partReportDTO = new ExportPartReportDTO();
                partReportDTO.setPartName(partBomTree.getName());

                List<String> codename = partIbaAttributeMap.get(codenameId);
                if (CollUtil.isNotEmpty(codename)) {
                    partReportDTO.setCodename(codename.get(0));
                } else {
                    partReportDTO.setCodename("");
                }

                List<String> material = partIbaAttributeMap.get(materialId);
                if (CollUtil.isNotEmpty(material)) {
                    partReportDTO.setMaterial(material.get(0));
                } else {
                    partReportDTO.setMaterial("");
                }

                List<String> ggxh = partIbaAttributeMap.get(ggxhId);
                if (CollUtil.isNotEmpty(ggxh)) {
                    partReportDTO.setSpecification(ggxh.get(0));
                } else {
                    partReportDTO.setSpecification("");
                }

                partReportDTO.setUnit(partBomTree.getUnitName());
                Double amount = partBomTree.getAmount() * parentPartAmount;
                partReportDTO.setQuantityPerUnit(String.valueOf(amount));
                result.put(partNumber,partReportDTO);
                HashSet<PartBomTree> children = partBomTree.getChildren();
                if (CollUtil.isNotEmpty(children)) {
                    for (PartBomTree child : children) {
                        dealElectricalData(child, result,codenameId,materialId,ggxhId,isElectricalId, amount);
                    }
                }
            }
        }
    }

    @Override
    public void exportProcessMaterialDetailReport(String partOid, HttpServletResponse response) {
        Map<String, String> ibaIdAndNameByType = getIbaIdAndNameByType(TableTypeConstrant.TY_PART_OTYPE);
        List<PartBomTree> partBomTreeList = queryPartBomTreeList(partOid);
        LinkedHashMap<String, ProductProcessMaterialDTO> result = new LinkedHashMap<>();
        PartBomTree partBomTree = partBomTreeList.get(0);
        String materialNumberId = ibaIdAndNameByType.get(PlmConstant.IBA_MATERIAL_NUMBER);
        String materialSpecId = ibaIdAndNameByType.get(PlmConstant.IBA_MATERIAL_SPECIFICATION);
        String materialNameId = ibaIdAndNameByType.get(PlmConstant.IBA_MATERIAL_NAME);
        String materialId = ibaIdAndNameByType.get(PlmConstant.IBA_MATERIAL);
        String ggxhId = ibaIdAndNameByType.get(PlmConstant.IBA_GGXH);
        dealProcessMaterialData(partBomTree,materialNumberId,materialSpecId,materialNameId,materialId,ggxhId,result);

        if(CollUtil.isNotEmpty( result)){
            String name = partBomTree.getName();
            List<String> modelValues = partBomTree.getPartIbaAttributeMap().get(ibaIdAndNameByType.get(PlmConstant.IBA_MODEL));
            String model = "";
            if(CollUtil.isNotEmpty( modelValues)){
                model = modelValues.get(0);
            }
            String templateFileName = commonService.getFilePath(productProcessMaterialList);
            ExportFileDTO destFile = commonService.getDestFile(partBomTree.getObjectNumber() + "产品工艺材料明细表");
            exportProcessMaterialDetailToExcel(result.values(),templateFileName,destFile,name,model,response);
        }
    }

    private void exportProcessMaterialDetailToExcel(Collection<ProductProcessMaterialDTO> values,
                                                    String templateFileName, ExportFileDTO fileDTO, String name,
                                                    String model, HttpServletResponse response) {
        File sourceFile = new File(templateFileName);
        File destFile = new File(fileDTO.getFilePath());
        try {
            copyModelFileToDestFile(destFile, sourceFile);

            FileInputStream fis = new FileInputStream(destFile);
            Workbook workbook = new XSSFWorkbook(fis);
            Sheet sheet = workbook.getSheetAt(0);

            CellStyle style = getCellStyle(workbook);

            createAndSetCell(sheet.getRow(2), 1, name, style);
            createAndSetCell(sheet.getRow(3), 1, model, style);

            int rowNum = 6;
            int i = 1;
            for (ProductProcessMaterialDTO dto : values) {
                Row row = sheet.createRow(rowNum++);
                createAndSetCell(row, 0, String.valueOf(i++), style); // 序号
                createAndSetCell(row, 1, StringUtils.defaultIfBlank(dto.getPartName(), ""), style);
                createAndSetCell(row, 2, StringUtils.defaultIfBlank(dto.getDrawingNumber(), ""), style);
                createAndSetCell(row, 3, StringUtils.defaultIfBlank(dto.getQuantityPerUnit(), ""), style);
                createAndSetCell(row, 4, StringUtils.defaultIfBlank(dto.getSpecification(), ""), style);
                createAndSetCell(row, 5, StringUtils.defaultIfBlank(dto.getMaterialName(), ""), style);
                createAndSetCell(row, 6, StringUtils.defaultIfBlank(dto.getMaterial(), ""), style);
                createAndSetCell(row, 7, StringUtils.defaultIfBlank(dto.getSingleSpecification(), ""), style);
                createAndSetCell(row, 8, StringUtils.defaultIfBlank(dto.getMaterialCode(), ""), style);
                createAndSetCell(row, 9, "", style);
                createAndSetCell(row, 10, StringUtils.defaultIfBlank(dto.getUnit(), ""), style);
                createAndSetCell(row, 11, "", style);
            }

            responseFile(fileDTO, response, workbook);
        }catch (Exception e){
            e.printStackTrace();
            throw new RuntimeException(e);
        }finally {
            destFile.delete();
        }

    }

    private static void copyModelFileToDestFile(File destFile, File sourceFile) throws IOException {
        // 确保目标文件的目录存在
        if (!destFile.getParentFile().exists()) {
            destFile.getParentFile().mkdirs();
        }
        // 使用 FileInputStream 和 FileOutputStream 复制文件
        try (FileInputStream fis = new FileInputStream(sourceFile);
             FileOutputStream fos = new FileOutputStream(destFile)) {
            byte[] buffer = new byte[1024];
            int length;
            while ((length = fis.read(buffer)) > 0) {
                fos.write(buffer, 0, length);
            }
        }
    }

    private static void responseFile(ExportFileDTO fileDTO, HttpServletResponse response, Workbook workbook)
            throws IOException {
        String fileName = fileDTO.getFileName();
        if(!fileName.contains(".xlsx")){
            fileName+=".xlsx";
        }

        String encodeFileName = URLEncoder.encode(fileName, "UTF-8").replace("\\+", "20%");
        if(fileName.contains(" ")){
            encodeFileName =encodeFileName.replace("+","%20");
        }
        response.setContentType("application/vnd.ms-excel");
        response.setHeader("Content-Disposition", "attachment;filename=" + encodeFileName);
        OutputStream outputStream = response.getOutputStream();
        workbook.write(outputStream); // 将Workbook对象写入流中
        response.setCharacterEncoding("UTF-8");
        outputStream.close();
        workbook.close();
    }

    private void dealProcessMaterialData(PartBomTree partBomTree,String materialNumberId,String materialSpecId,String materialNameId,String materialId,String ggxhId,
                                         LinkedHashMap<String, ProductProcessMaterialDTO> result) {
        HashSet<PartBomTree> children = partBomTree.getChildren();
        if(CollUtil.isEmpty(children)){
            Map<String, List<String>> partIbaAttributeMap = partBomTree.getPartIbaAttributeMap();
            ProductProcessMaterialDTO dto = new ProductProcessMaterialDTO();
            dto.setPartName(partBomTree.getName());
            dto.setDrawingNumber(partBomTree.getObjectNumber());
            dto.setQuantityPerUnit(String.valueOf(partBomTree.getAmount()));
            String materialSpec = getIbaValue(partIbaAttributeMap, materialSpecId);
            dto.setSingleSpecification(materialSpec);
            dto.setMaterialName(getIbaValue(partIbaAttributeMap, materialNameId));
            dto.setMaterial(getIbaValue(partIbaAttributeMap, materialId));
            dto.setSpecification(getIbaValue(partIbaAttributeMap, ggxhId));

            String materialNumber = getIbaValue(partIbaAttributeMap, materialNumberId);
            if(StringUtils.isNotBlank(materialNumber) && StringUtils.isNotEmpty(materialNumber)) {
                dto.setMaterialCode(materialNumber);
            }else {
                BigInteger classficationOid = partBomTree.getClassficationOid();
                if(classficationOid != null && StringUtils.isNotBlank(materialSpec) && StringUtils.isNotBlank(materialSpec)){
                    log.info("============提示信息==============> 查询物料编号，classficationOid：{}，materialSpec：{}", classficationOid,materialSpec);
                    List<String> list = commonMapper.queryLatestPartByClassIdAndSpec(classficationOid,materialSpec);
                    List<BigInteger> partIdList = list.stream().map(String::trim).map(BigInteger::new).collect(Collectors.toList());
                    List<String> ibaValueDTOS = commonMapper.queryIbaValueByOids(partIdList);
                    String materialNumbers = ibaValueDTOS.stream().collect(Collectors.joining(","));
                    log.info("============提示信息==============> 查询物料编号结果：{}", materialNumbers);
                    dto.setMaterialCode(materialNumbers);
                }
//                PartDO partDO = commonMapper.queryLatestPartByNumberAndView(materialNumber, "Design", "");
//                if(partDO != null){
//                    BigInteger oid = partDO.getOid();
//                    List<IbaValueDTO> ibaValueDTOS = commonMapper.queryIbaValueByOids(Collections.singletonList(oid));
//                    if(CollUtil.isNotEmpty(ibaValueDTOS)){
//                        IbaValueDTO ibaValueDTO = ibaValueDTOS.get(0);
//                        dto.setMaterialName(ibaValueDTO.getMaterialName());
//                        dto.setMaterial(ibaValueDTO.getMaterial());
//                        dto.setSpecification(ibaValueDTO.getMaterialSpecification());
//                    }
//                }else {
//                    BigInteger classficationOid = partBomTree.getClassficationOid();
//                    List<String> list = commonMapper.queryLatestPartByClassIdAndSpec(classficationOid,materialSpec);
//                    List<BigInteger> partIdList = list.stream().map(String::trim).map(BigInteger::new).collect(Collectors.toList());
//                    List<IbaValueDTO> ibaValueDTOS = commonMapper.queryIbaValueByOids(partIdList);
//                    if(CollUtil.isNotEmpty(ibaValueDTOS)){
//                        StringBuilder materialName = new StringBuilder();
//                        StringBuilder material = new StringBuilder();
//                        StringBuilder materialSpecification = new StringBuilder();
//                        for (IbaValueDTO ibaValueDTO : ibaValueDTOS) {
//                            materialName.append(ibaValueDTO.getMaterialName()).append(";");
//                            material.append(ibaValueDTO.getMaterial()).append(";");
//                            materialSpecification.append(ibaValueDTO.getMaterialSpecification()).append(";");
//                        }
//                        dto.setMaterialName(String.valueOf(materialName));
//                        dto.setMaterial(String.valueOf(material));
//                        dto.setSpecification(String.valueOf(materialSpecification));
//                    }
//                }
            }
            dto.setUnit(partBomTree.getUnitName());
            result.put(partBomTree.getObjectNumber(),dto);
        }else {
            for (PartBomTree child : children) {
                dealProcessMaterialData(child,materialNumberId, materialSpecId, materialNameId, materialId, ggxhId, result);
            }
        }
    }

    private static String getIbaValue(Map<String, List<String>> partIbaAttributeMap, String ibaId) {
        if (partIbaAttributeMap.containsKey(ibaId)){
            List<String> ibaValues = partIbaAttributeMap.get(ibaId);
            if (CollUtil.isNotEmpty(ibaValues)) {
                return ibaValues.get(0);
            } else {
                return "";
            }
        } else {
            return "";
        }
    }
}
